/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 * Origin source from MaNGOS(GPL2).
 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
 */

#ifndef __WORLD_H__
#define __WORLD_H__

#include "Common.h"
#include "Database.h"
#include "Timer.h"
#include "UnorderedMapSet.h"
#include "WorldSession.h"

#include "ace/Atomic_Op.h"

namespace PQCore
{
	
	class Player;
	class Weather;
	class WorldSession;
	
	/// Type of server, this is values from second column of Cfg_Configs.dbc (1.12.1 have another numeration)
	enum RealmType
	{
		REALM_TYPE_NORMAL   = 0,
		REALM_TYPE_PVP      = 1,
		REALM_TYPE_NORMAL2  = 4,
		REALM_TYPE_RP       = 6,
		REALM_TYPE_RPPVP    = 8,
		REALM_TYPE_FFA_PVP  = 16
		// custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
		// replaced by REALM_PVP in realm list
	};


	/// Timers for different object refresh rates
	enum WorldTimers
	{
		WUPDATE_OBJECTS     = 0,
		WUPDATE_SESSIONS    = 1,
		WUPDATE_AUCTIONS    = 2,
		WUPDATE_WEATHERS    = 3,
		WUPDATE_UPTIME      = 4,
		WUPDATE_CORPSES     = 5,
		WUPDATE_EVENTS      = 6,
		WUPDATE_DELETECHARS = 7,
		WUPDATE_COUNT       = 8
	};

	/// This is values from first column of Cfg_Categories.dbc (1.12.1 have another numeration)
	enum RealmZone
	{
		REALM_ZONE_UNKNOWN       = 0,                           // any language
		REALM_ZONE_DEVELOPMENT   = 1,                           // any language
		REALM_ZONE_UNITED_STATES = 2,                           // extended-Latin
		REALM_ZONE_OCEANIC       = 3,                           // extended-Latin
		REALM_ZONE_LATIN_AMERICA = 4,                           // extended-Latin
		REALM_ZONE_TOURNAMENT_5  = 5,                           // basic-Latin at create, any at login
		REALM_ZONE_KOREA         = 6,                           // East-Asian
		REALM_ZONE_TOURNAMENT_7  = 7,                           // basic-Latin at create, any at login
		REALM_ZONE_ENGLISH       = 8,                           // extended-Latin
		REALM_ZONE_GERMAN        = 9,                           // extended-Latin
		REALM_ZONE_FRENCH        = 10,                          // extended-Latin
		REALM_ZONE_SPANISH       = 11,                          // extended-Latin
		REALM_ZONE_RUSSIAN       = 12,                          // Cyrillic
		REALM_ZONE_TOURNAMENT_13 = 13,                          // basic-Latin at create, any at login
		REALM_ZONE_TAIWAN        = 14,                          // East-Asian
		REALM_ZONE_TOURNAMENT_15 = 15,                          // basic-Latin at create, any at login
		REALM_ZONE_CHINA         = 16,                          // East-Asian
		REALM_ZONE_CN1           = 17,                          // basic-Latin at create, any at login
		REALM_ZONE_CN2           = 18,                          // basic-Latin at create, any at login
		REALM_ZONE_CN3           = 19,                          // basic-Latin at create, any at login
		REALM_ZONE_CN4           = 20,                          // basic-Latin at create, any at login
		REALM_ZONE_CN5           = 21,                          // basic-Latin at create, any at login
		REALM_ZONE_CN6           = 22,                          // basic-Latin at create, any at login
		REALM_ZONE_CN7           = 23,                          // basic-Latin at create, any at login
		REALM_ZONE_CN8           = 24,                          // basic-Latin at create, any at login
		REALM_ZONE_TOURNAMENT_25 = 25,                          // basic-Latin at create, any at login
		REALM_ZONE_TEST_SERVER   = 26,                          // any language
		REALM_ZONE_TOURNAMENT_27 = 27,                          // basic-Latin at create, any at login
		REALM_ZONE_QA_SERVER     = 28,                          // any language
		REALM_ZONE_CN9           = 29,                          // basic-Latin at create, any at login
		REALM_ZONE_TEST_SERVER_2 = 30,                          // any language
		// in 3.x
		REALM_ZONE_CN10          = 31,                          // basic-Latin at create, any at login
		REALM_ZONE_CTC           = 32,
		REALM_ZONE_CNC           = 33,
		REALM_ZONE_CN1_4         = 34,                          // basic-Latin at create, any at login
		REALM_ZONE_CN2_6_9       = 35,                          // basic-Latin at create, any at login
		REALM_ZONE_CN3_7         = 36,                          // basic-Latin at create, any at login
		REALM_ZONE_CN5_8         = 37                           // basic-Latin at create, any at login
	};


	/// Configuration elements
	enum ConfigUInt32Values
	{
		CONFIG_UINT32_COMPRESSION = 0,
		CONFIG_UINT32_INTERVAL_SAVE,
		CONFIG_UINT32_INTERVAL_GRIDCLEAN,
		CONFIG_UINT32_INTERVAL_MAPUPDATE,
		CONFIG_UINT32_INTERVAL_CHANGEWEATHER,
		CONFIG_UINT32_PORT_WORLD,
		CONFIG_UINT32_SOCKET_SELECTTIME,
		CONFIG_UINT32_GAME_TYPE,
		CONFIG_UINT32_REALM_ZONE,
		CONFIG_UINT32_STRICT_PLAYER_NAMES,
		CONFIG_UINT32_STRICT_CHARTER_NAMES,
		CONFIG_UINT32_STRICT_PET_NAMES,
		CONFIG_UINT32_MIN_PLAYER_NAME,
		CONFIG_UINT32_MIN_CHARTER_NAME,
		CONFIG_UINT32_MIN_PET_NAME,
		CONFIG_UINT32_CHARACTERS_CREATING_DISABLED,
		CONFIG_UINT32_CHARACTERS_PER_ACCOUNT,
		CONFIG_UINT32_CHARACTERS_PER_REALM,
		CONFIG_UINT32_HEROIC_CHARACTERS_PER_REALM,
		CONFIG_UINT32_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,
		CONFIG_UINT32_SKIP_CINEMATICS,
		CONFIG_UINT32_MAX_PLAYER_LEVEL,
		CONFIG_UINT32_START_PLAYER_LEVEL,
		CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL,
		CONFIG_UINT32_START_PLAYER_MONEY,
		CONFIG_UINT32_MAX_HONOR_POINTS,
		CONFIG_UINT32_START_HONOR_POINTS,
		CONFIG_UINT32_MAX_ARENA_POINTS,
		CONFIG_UINT32_START_ARENA_POINTS,
		CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR,
		CONFIG_UINT32_INSTANCE_UNLOAD_DELAY,
		CONFIG_UINT32_MAX_SPELL_CASTS_IN_CHAIN,
		CONFIG_UINT32_MAX_PRIMARY_TRADE_SKILL,
		CONFIG_UINT32_MIN_PETITION_SIGNS,
		CONFIG_UINT32_GM_LOGIN_STATE,
		CONFIG_UINT32_GM_VISIBLE_STATE,
		CONFIG_UINT32_GM_ACCEPT_TICKETS,
		CONFIG_UINT32_GM_CHAT,
		CONFIG_UINT32_GM_WISPERING_TO,
		CONFIG_UINT32_GM_LEVEL_IN_GM_LIST,
		CONFIG_UINT32_GM_LEVEL_IN_WHO_LIST,
		CONFIG_UINT32_START_GM_LEVEL,
		CONFIG_UINT32_GROUP_VISIBILITY,
		CONFIG_UINT32_MAIL_DELIVERY_DELAY,
		CONFIG_UINT32_UPTIME_UPDATE,
		CONFIG_UINT32_AUCTION_DEPOSIT_MIN,
		CONFIG_UINT32_SKILL_CHANCE_ORANGE,
		CONFIG_UINT32_SKILL_CHANCE_YELLOW,
		CONFIG_UINT32_SKILL_CHANCE_GREEN,
		CONFIG_UINT32_SKILL_CHANCE_GREY,
		CONFIG_UINT32_SKILL_CHANCE_MINING_STEPS,
		CONFIG_UINT32_SKILL_CHANCE_SKINNING_STEPS,
		CONFIG_UINT32_SKILL_GAIN_CRAFTING,
		CONFIG_UINT32_SKILL_GAIN_DEFENSE,
		CONFIG_UINT32_SKILL_GAIN_GATHERING,
		CONFIG_UINT32_SKILL_GAIN_WEAPON,
		CONFIG_UINT32_MAX_OVERSPEED_PINGS,
		CONFIG_UINT32_EXPANSION,
		CONFIG_UINT32_CHATFLOOD_MESSAGE_COUNT,
		CONFIG_UINT32_CHATFLOOD_MESSAGE_DELAY,
		CONFIG_UINT32_CHATFLOOD_MUTE_TIME,
		CONFIG_UINT32_CREATURE_FAMILY_ASSISTANCE_DELAY,
		CONFIG_UINT32_CREATURE_FAMILY_FLEE_DELAY,
		CONFIG_UINT32_WORLD_BOSS_LEVEL_DIFF,
		CONFIG_UINT32_QUEST_LOW_LEVEL_HIDE_DIFF,
		CONFIG_UINT32_QUEST_HIGH_LEVEL_HIDE_DIFF,
		CONFIG_UINT32_QUEST_DAILY_RESET_HOUR,
		CONFIG_UINT32_QUEST_WEEKLY_RESET_WEEK_DAY,
		CONFIG_UINT32_QUEST_WEEKLY_RESET_HOUR,
		CONFIG_UINT32_CHAT_STRICT_LINK_CHECKING_SEVERITY,
		CONFIG_UINT32_CHAT_STRICT_LINK_CHECKING_KICK,
		CONFIG_UINT32_CORPSE_DECAY_NORMAL,
		CONFIG_UINT32_CORPSE_DECAY_RARE,
		CONFIG_UINT32_CORPSE_DECAY_ELITE,
		CONFIG_UINT32_CORPSE_DECAY_RAREELITE,
		CONFIG_UINT32_CORPSE_DECAY_WORLDBOSS,
		CONFIG_UINT32_INSTANT_LOGOUT,
		CONFIG_UINT32_BATTLEGROUND_INVITATION_TYPE,
		CONFIG_UINT32_BATTLEGROUND_PREMATURE_FINISH_TIMER,
		CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,
		CONFIG_UINT32_BATTLEGROUND_QUEUE_ANNOUNCER_JOIN,
		CONFIG_UINT32_ARENA_MAX_RATING_DIFFERENCE,
		CONFIG_UINT32_ARENA_RATING_DISCARD_TIMER,
		CONFIG_UINT32_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
		CONFIG_UINT32_ARENA_SEASON_ID,
		CONFIG_UINT32_ARENA_SEASON_PREVIOUS_ID,
		CONFIG_UINT32_CLIENTCACHE_VERSION,
		CONFIG_UINT32_GUILD_EVENT_LOG_COUNT,
		CONFIG_UINT32_GUILD_BANK_EVENT_LOG_COUNT,
		CONFIG_UINT32_TIMERBAR_FATIGUE_GMLEVEL,
		CONFIG_UINT32_TIMERBAR_FATIGUE_MAX,
		CONFIG_UINT32_TIMERBAR_BREATH_GMLEVEL,
		CONFIG_UINT32_TIMERBAR_BREATH_MAX,
		CONFIG_UINT32_TIMERBAR_FIRE_GMLEVEL,
		CONFIG_UINT32_TIMERBAR_FIRE_MAX,
		CONFIG_UINT32_MIN_LEVEL_STAT_SAVE,
		CONFIG_UINT32_CHARDELETE_KEEP_DAYS,
		CONFIG_UINT32_CHARDELETE_METHOD,
		CONFIG_UINT32_CHARDELETE_MIN_LEVEL,
		CONFIG_UINT32_VALUE_COUNT
	};

	enum ConfigInt32Values
	{
		CONFIG_INT32_DEATH_SICKNESS_LEVEL = 0,
		CONFIG_INT32_ARENA_STARTRATING,
		CONFIG_INT32_ARENA_STARTPERSONALRATING,
		CONFIG_INT32_VALUE_COUNT
	};

	/// Server config
	enum ConfigFloatValues
	{
		CONFIG_FLOAT_RATE_HEALTH = 0,
		CONFIG_FLOAT_RATE_POWER_MANA,
		CONFIG_FLOAT_RATE_POWER_RAGE_INCOME,
		CONFIG_FLOAT_RATE_POWER_RAGE_LOSS,
		CONFIG_FLOAT_RATE_POWER_RUNICPOWER_INCOME,
		CONFIG_FLOAT_RATE_POWER_RUNICPOWER_LOSS,
		CONFIG_FLOAT_RATE_POWER_FOCUS,
		CONFIG_FLOAT_RATE_POWER_ENERGY,
		CONFIG_FLOAT_RATE_SKILL_DISCOVERY,
		CONFIG_FLOAT_RATE_DROP_ITEM_POOR,
		CONFIG_FLOAT_RATE_DROP_ITEM_NORMAL,
		CONFIG_FLOAT_RATE_DROP_ITEM_UNCOMMON,
		CONFIG_FLOAT_RATE_DROP_ITEM_RARE,
		CONFIG_FLOAT_RATE_DROP_ITEM_EPIC,
		CONFIG_FLOAT_RATE_DROP_ITEM_LEGENDARY,
		CONFIG_FLOAT_RATE_DROP_ITEM_ARTIFACT,
		CONFIG_FLOAT_RATE_DROP_ITEM_REFERENCED,
		CONFIG_FLOAT_RATE_DROP_MONEY,
		CONFIG_FLOAT_RATE_XP_KILL,
		CONFIG_FLOAT_RATE_XP_QUEST,
		CONFIG_FLOAT_RATE_XP_EXPLORE,
		CONFIG_FLOAT_RATE_REPUTATION_GAIN,
		CONFIG_FLOAT_RATE_REPUTATION_LOWLEVEL_KILL,
		CONFIG_FLOAT_RATE_REPUTATION_LOWLEVEL_QUEST,
		CONFIG_FLOAT_RATE_CREATURE_NORMAL_HP,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_HP,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RAREELITE_HP,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_WORLDBOSS_HP,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RARE_HP,
		CONFIG_FLOAT_RATE_CREATURE_NORMAL_DAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_DAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RAREELITE_DAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RARE_DAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_NORMAL_SPELLDAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_ELITE_RARE_SPELLDAMAGE,
		CONFIG_FLOAT_RATE_CREATURE_AGGRO,
		CONFIG_FLOAT_RATE_REST_INGAME,
		CONFIG_FLOAT_RATE_REST_OFFLINE_IN_TAVERN_OR_CITY,
		CONFIG_FLOAT_RATE_REST_OFFLINE_IN_WILDERNESS,
		CONFIG_FLOAT_RATE_DAMAGE_FALL,
		CONFIG_FLOAT_RATE_AUCTION_TIME,
		CONFIG_FLOAT_RATE_AUCTION_DEPOSIT,
		CONFIG_FLOAT_RATE_AUCTION_CUT,
		CONFIG_FLOAT_RATE_HONOR,
		CONFIG_FLOAT_RATE_MINING_AMOUNT,
		CONFIG_FLOAT_RATE_MINING_NEXT,
		CONFIG_FLOAT_RATE_TALENT,
		CONFIG_FLOAT_RATE_CORPSE_DECAY_LOOTED,
		CONFIG_FLOAT_RATE_INSTANCE_RESET_TIME,
		CONFIG_FLOAT_RATE_TARGET_POS_RECALCULATION_RANGE,
		CONFIG_FLOAT_RATE_DURABILITY_LOSS_DAMAGE,
		CONFIG_FLOAT_RATE_DURABILITY_LOSS_PARRY,
		CONFIG_FLOAT_RATE_DURABILITY_LOSS_ABSORB,
		CONFIG_FLOAT_RATE_DURABILITY_LOSS_BLOCK,
		CONFIG_FLOAT_SIGHT_GUARDER,
		CONFIG_FLOAT_SIGHT_MONSTER,
		CONFIG_FLOAT_LISTEN_RANGE_SAY,
		CONFIG_FLOAT_LISTEN_RANGE_YELL,
		CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE,
		CONFIG_FLOAT_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS,
		CONFIG_FLOAT_CREATURE_FAMILY_ASSISTANCE_RADIUS,
		CONFIG_FLOAT_GROUP_XP_DISTANCE,
		CONFIG_FLOAT_THREAT_RADIUS,
		CONFIG_FLOAT_VALUE_COUNT
	};

	/// Configuration elements
	enum ConfigBoolValues
	{
		CONFIG_BOOL_GRID_UNLOAD = 0,
		CONFIG_BOOL_SAVE_RESPAWN_TIME_IMMEDIATLY,
		CONFIG_BOOL_OFFHAND_CHECK_AT_TALENTS_RESET,
		CONFIG_BOOL_ALLOW_TWO_SIDE_ACCOUNTS,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHANNEL,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_AUCTION,
		CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_MAIL,
		CONFIG_BOOL_ALLOW_TWO_SIDE_WHO_LIST,
		CONFIG_BOOL_ALLOW_TWO_SIDE_ADD_FRIEND,
		CONFIG_BOOL_INSTANCE_IGNORE_LEVEL,
		CONFIG_BOOL_INSTANCE_IGNORE_RAID,
		CONFIG_BOOL_CAST_UNSTUCK,
		CONFIG_BOOL_GM_LOG_TRADE,
		CONFIG_BOOL_GM_LOWER_SECURITY,
		CONFIG_BOOL_GM_ALLOW_ACHIEVEMENT_GAINS,
		CONFIG_BOOL_SKILL_PROSPECTING,
		CONFIG_BOOL_ALWAYS_MAX_SKILL_FOR_LEVEL,
		CONFIG_BOOL_WEATHER,
		CONFIG_BOOL_EVENT_ANNOUNCE,
		CONFIG_BOOL_QUEST_IGNORE_RAID,
		CONFIG_BOOL_DETECT_POS_COLLISION,
		CONFIG_BOOL_RESTRICTED_LFG_CHANNEL,
		CONFIG_BOOL_SILENTLY_GM_JOIN_TO_CHANNEL,
		CONFIG_BOOL_TALENTS_INSPECTING,
		CONFIG_BOOL_CHAT_FAKE_MESSAGE_PREVENTING,
		CONFIG_BOOL_CHAT_STRICT_LINK_CHECKING_SEVERITY,
		CONFIG_BOOL_CHAT_STRICT_LINK_CHECKING_KICK,
		CONFIG_BOOL_ADDON_CHANNEL,
		CONFIG_BOOL_CORPSE_EMPTY_LOOT_SHOW,
		CONFIG_BOOL_DEATH_CORPSE_RECLAIM_DELAY_PVP,
		CONFIG_BOOL_DEATH_CORPSE_RECLAIM_DELAY_PVE,
		CONFIG_BOOL_DEATH_BONES_WORLD,
		CONFIG_BOOL_DEATH_BONES_BG_OR_ARENA,
		CONFIG_BOOL_ALL_TAXI_PATHS,
		CONFIG_BOOL_DECLINED_NAMES_USED,
		CONFIG_BOOL_SKILL_MILLING,
		CONFIG_BOOL_BATTLEGROUND_CAST_DESERTER,
		CONFIG_BOOL_BATTLEGROUND_QUEUE_ANNOUNCER_START,
		CONFIG_BOOL_ARENA_AUTO_DISTRIBUTE_POINTS,
		CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_JOIN,
		CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_EXIT,
		CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET,
		CONFIG_BOOL_STATS_SAVE_ONLY_ON_LOGOUT,
		CONFIG_BOOL_CLEAN_CHARACTER_DB,
		CONFIG_BOOL_VMAP_INDOOR_CHECK,
		CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT,
		CONFIG_BOOL_VALUE_COUNT
	};

	enum ShutdownMask
	{
		SHUTDOWN_MASK_RESTART = 1,
		SHUTDOWN_MASK_IDLE    = 2,
	};


	// ServerMessages.dbc
	enum ServerMessageType
	{
		SERVER_MSG_SHUTDOWN_TIME      = 1,
		SERVER_MSG_RESTART_TIME       = 2,
		SERVER_MSG_STRING             = 3,
		SERVER_MSG_SHUTDOWN_CANCELLED = 4,
		SERVER_MSG_RESTART_CANCELLED  = 5
	};


	class World
	{
	public:
		typedef UNORDERED_MAP<uint32, Weather*> WeatherMap;
        typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
        typedef std::list<WorldSession*> SessionQueue;

	public:
		World();
		static World& getSingleton()
		{
			static World inst;
			return inst;
		}
	public:
		/*Initialize the game world.
		*/
		 void initWorldSetting();

		 /*Load config values
		 */
		void loadConfigSetting(bool reload = false);
		
		 /*Set the active session security level limitation.
		 */
        void setPlayerLimit(int limit, bool needUpdate = false);

		/* Set a new Message of the Day
		*/
        void setDayMsg(const std::string& msg) { _dayMsg = msg; }

		 /// Are we on a "Player versus Player" server?
        bool IsPvPRealm() { return (getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
        bool IsFFAPvPRealm() { return getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP; }

		LocaleConstant GetDefaultDbcLocale() const { return _defaultDbcLocale; }
		
		 void UpdateResultQueue();
		 void ProcessCliCommands();

		 //sessions that are added async
        void addWorldSession(WorldSession* session);
		LockedQueue<WorldSession*, ACE_Thread_Mutex> _sessionQueueAdd;//add and wait

		bool RemoveSession(uint32 id);

		 /// Get the active session server limit (or security level limitations)
		uint32 GetPlayerAmountLimit() const { return _playerLimit >= 0 ? _playerLimit : 0; }
        //AccountTypes GetPlayerSecurityLimit() const { return _playerLimit <= 0 ? AccountTypes(-_playerLimit) : SEC_PLAYER; }
		uint32 GetQueueSize() const { return _queuedPlayer.size(); }
		uint32 GetActiveSessionCount() const { return _sessions.size() - _queuedPlayer.size(); }
	private:
		void setConfig(ConfigUInt32Values index, char const* fieldname, uint32 defvalue);
        void setConfig(ConfigInt32Values index, char const* fieldname, int32 defvalue);
        void setConfig(ConfigFloatValues index, char const* fieldname, float defvalue);
        void setConfig(ConfigBoolValues index, char const* fieldname, bool defvalue);
        void setConfigPos(ConfigUInt32Values index, char const* fieldname, uint32 defvalue);
        void setConfigPos(ConfigFloatValues index, char const* fieldname, float defvalue);
        void setConfigMin(ConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue);
        void setConfigMin(ConfigInt32Values index, char const* fieldname, int32 defvalue, int32 minvalue);
        void setConfigMin(ConfigFloatValues index, char const* fieldname, float defvalue, float minvalue);
        void setConfigMinMax(ConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue);
        void setConfigMinMax(ConfigInt32Values index, char const* fieldname, int32 defvalue, int32 minvalue, int32 maxvalue);
        void setConfigMinMax(ConfigFloatValues index, char const* fieldname, float defvalue, float minvalue, float maxvalue);
        bool configNoReload(bool reload, ConfigUInt32Values index, char const* fieldname, uint32 defvalue);
        bool configNoReload(bool reload, ConfigInt32Values index, char const* fieldname, int32 defvalue);
        bool configNoReload(bool reload, ConfigFloatValues index, char const* fieldname, float defvalue);
        bool configNoReload(bool reload, ConfigBoolValues index, char const* fieldname, bool defvalue);

	public:
		 /// Get a server configuration element (see #ConfigFloatValues)
        void setConfig(ConfigFloatValues index,float value) { _configFloatValues[index]=value; }
        /// Get a server configuration element (see #ConfigFloatValues)
        float getConfig(ConfigFloatValues rate) const { return _configFloatValues[rate]; }

        /// Set a server configuration element (see #ConfigUInt32Values)
        void setConfig(ConfigUInt32Values index, uint32 value) { _configUInt32Values[index]=value; }
        /// Get a server configuration element (see #ConfigUInt32Values)
        uint32 getConfig(ConfigUInt32Values index) const { return _configUInt32Values[index]; }

        /// Set a server configuration element (see #ConfigInt32Values)
        void setConfig(ConfigInt32Values index, int32 value) { _configInt32Values[index]=value; }
        /// Get a server configuration element (see #eConfigInt32Values)
        int32 getConfig(ConfigInt32Values index) const { return _configInt32Values[index]; }

        /// Set a server configuration element (see #ConfigBoolValues)
        void setConfig(ConfigBoolValues index, bool value) { _configBoolValues[index]=value; }
        /// Get a server configuration element (see #ConfigBoolValues)
        bool getConfig(ConfigBoolValues index) const { return _configBoolValues[index]; }

	private:
		int _playerLimit;
		bool _allowMovement;
		

		std::string _dayMsg;
		std::string _dataPath;

		uint32 _shutdownMask;
		uint32 _shutdownTimer;

		time_t _startTime;
		time_t _gameTime;

		uint32 _maxActiveSessionCount;
		uint32 _maxQueuedSessionCount;

		SqlResultQueue* _resultQueue;

		 // next daily quests reset time
		time_t _nextDailyQuestReset;
		time_t _nextWeeklyQuestReset;

		//atomic op counter for active scripts amount
        ACE_Atomic_Op<ACE_Thread_Mutex, long> _scheduledScripts;

		// from config for one from loaded DBC locales
		LocaleConstant _defaultDbcLocale;

		// by loaded DBC
		uint32 _availableDbcLocaleMask;
		
		uint32 _configUInt32Values[CONFIG_UINT32_VALUE_COUNT];
        int32 _configInt32Values[CONFIG_INT32_VALUE_COUNT];
        float _configFloatValues[CONFIG_FLOAT_VALUE_COUNT];
        bool _configBoolValues[CONFIG_BOOL_VALUE_COUNT];
		
		IntervalTimer _timers[WUPDATE_COUNT];
		uint32 _mailTimer;
        uint32 _mailTimerExpires;
	private:
		 // for max speed access
        static float _maxVisibleDistanceOnContinents;
        static float _maxVisibleDistanceInInstances;
        static float _maxVisibleDistanceInBGArenas;
        static float _maxVisibleDistanceForObject;

        static float _maxVisibleDistanceInFlight;
        static float _visibleUnitGreyDistance;
        static float _visibleObjectGreyDistance;
	private:
		uint32 realmID;//realmId should be global?BUG:
		WeatherMap _weathers;
        SessionMap _sessions;
		SessionQueue _queuedPlayer;
	private:
		void detectDBCLang();
		void InitDailyQuestResetTime();
        void InitWeeklyQuestResetTime();
        void ResetDailyQuests();
        void ResetWeeklyQuests();
		void AddQueuedPlayer(WorldSession* session);
		void UpdateMaxSessionCounters();
	public:
		void InitResultQueue();
		void Update(uint32 deltaT);
		void UpdateSessions(uint32 deltaT);
		void KickAll();

        bool RemoveQueuedPlayer(WorldSession* session);


		uint32 GetActiveAndQueuedSessionCount() const { return _sessions.size(); }
		uint32 GetMaxActiveSessionCount() const { return _maxActiveSessionCount; }
		LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const { if(_availableDbcLocaleMask & (1 << locale)) return locale; else return _defaultDbcLocale; }

		/* Display a shutdown message to the player
		*/
		void ShutdownMsg(bool show = false, Player* player = 0);
		static bool IsStoped(){return _stopEvent;}
		static void incLoopCounter(){++_loopCounter;}
	protected:
		void updateGameTime();
	private:
		static volatile uint32 _loopCounter;
		static volatile bool _stopEvent;
	
	};

}

#define SWorld PQCore::World::getSingleton()

#endif
